home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / intrlib1.zip / INPUT.C < prev    next >
C/C++ Source or Header  |  1992-03-10  |  26KB  |  822 lines

  1. /******************************************************************************
  2. * Iteraction library - input handler.                          *
  3. *                                          *
  4. *                    Written by Gershon Elber,  Oct. 1990  *
  5. *******************************************************************************
  6. * Supported device:                                  *
  7. * 1. Keyboard.                                      *
  8. * 2. Mouse (MS compatible).                              *
  9. * 3. Joystick (uses AT class BIOS intrrupt 0x15, ah = 0x84).              *
  10. *******************************************************************************
  11. * History:                                      *
  12. *  3 Oct 90 - Version 1.0 by Gershon Elber.                      *
  13. *  17 Feb 92 - Version 2.0 by Gershon Elber - support for DJGPP.          *
  14. ******************************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <dos.h>
  18.  
  19. #ifdef __MSDOS__
  20. #include <conio.h>
  21. #include "mousedrv.h"
  22. #endif /* _MSDOS__ */
  23.  
  24. #ifdef DJGCC
  25. #include <mouse.h>
  26. #endif /* DJGCC */
  27.  
  28. #include "intr_loc.h"
  29. #include "intr_gr.h"
  30.  
  31. #define MAX_REGISTERED_KEYS    50     /* Maximum number of registered keys. */
  32. #define JOYSTICK_MAX_MOVE    10    /* Maximum single joystick movement. */
  33. #define JOYSTICK_INC_MOVE    4           /* Increment movement factor. */
  34.  
  35. #define SHIFT_KEY_MOVES        12
  36.  
  37. typedef struct {
  38.     int KeyStroke;
  39.     IntrIntFunc ActionFunc;
  40. } RegisterKeyStruct;
  41.  
  42. int _IntrActiveDevices = 0;
  43. IntrBType _IntrDetachKbdFromMouse = FALSE;
  44.  
  45. static int
  46.     IntrATKeyboard = FALSE,           /* If support AT style keyboard bios. */
  47.     NumOfRegisteredKeys = 0,
  48.     PushedKbdEvent = -1,
  49.     JoystickMinX = 0,
  50.     JoystickMaxX = 255,
  51.     JoystickMinY = 0,
  52.     JoystickMaxY = 255,
  53.     JoystickCenterX = 128,
  54.     JoystickCenterY = 128,
  55.     JoystickTolerance = 16,
  56.     MouseSensitivity = 16,
  57.     LastInputChar = -1;
  58. static IntrBType
  59.     HandleInternalEvents = TRUE,
  60.     PropagateInternalEvents = TRUE,
  61.     NoJoystick = TRUE;
  62. static RegisterKeyStruct RegisteredKeys[MAX_REGISTERED_KEYS];
  63. static IntrVoidFunc
  64.     IntrIdleFunction = NULL;
  65.  
  66. static void IntrFlushKbd(void);
  67. static int UpdateGetPointKbd(int *Dx, int *Dy);
  68. static int JoystickMove(int *Dx, int *Dy, IntrEventType *Event);
  69. static void JoystickWaitButton0(void);
  70. static void JoystickWaitButton1(void);
  71.  
  72. /****************************************************************************
  73. * Routine to set the function to execute on idle.                *
  74. ****************************************************************************/
  75. void IntrSetIdleFunction(IntrVoidFunc IdleFunction)
  76. {
  77.     IntrIdleFunction = IdleFunction;
  78. }
  79.  
  80. /****************************************************************************
  81. * Routine to set an AT bios support for keyboard.                *
  82. ****************************************************************************/
  83. void IntrSetAtKeyboard(IntrBType IsATKeyboard)
  84. {
  85.     IntrATKeyboard = IsATKeyboard;
  86. }
  87. /****************************************************************************
  88. * Routine to draw cursor shape at given location. Shape is specified by     *
  89. * CurrentCursor variable.                            *
  90. ****************************************************************************/
  91. void IntrSetMouseSensitivity(int Sensitivity)
  92. {
  93.     MouseSensitivity = Sensitivity;
  94. }
  95.  
  96. /****************************************************************************
  97. * Routine to register a KeyStroke. Returns TRUE if O.K.                *
  98. * If stroke is regular ASCII it must be <256. >256 signals it is enhanced.  *
  99. ****************************************************************************/
  100. IntrBType IntrRegisterKeyStroke(int KeyStroke, IntrIntFunc ActionFunc)
  101. {
  102.     if (NumOfRegisteredKeys >= MAX_REGISTERED_KEYS)
  103.     return FALSE;
  104.     else {
  105.         RegisteredKeys[NumOfRegisteredKeys].KeyStroke = KeyStroke;
  106.         RegisteredKeys[NumOfRegisteredKeys++].ActionFunc = ActionFunc;
  107.         return TRUE;
  108.     }
  109. }
  110.  
  111. /****************************************************************************
  112. * Routine to test if given key is registered. If TRUE the relative        *
  113. * registered function ActionFunc is been applied.                *
  114. ****************************************************************************/
  115. static IntrBType IsRegisteredKey(int KeyStroke)
  116. {
  117.     int i;
  118.  
  119.     /* Dont activate any registered function if something is been pop up. */
  120.     if (!_IntrAllowInternalEvent()) return FALSE;
  121.  
  122.     for (i = 0; i < NumOfRegisteredKeys; i++)
  123.     if (RegisteredKeys[i].KeyStroke == KeyStroke) {
  124.             if (RegisteredKeys[i].ActionFunc != NULL)
  125.         RegisteredKeys[i].ActionFunc(KeyStroke);
  126.         return TRUE;
  127.         }
  128.  
  129.     return FALSE;
  130. }
  131.  
  132. /****************************************************************************
  133. * Routine to get one character from the keyboard. If IntrATKeyboard is set  *
  134. * then it is assumed AT style keyboard bios calls are supported.        *
  135. ****************************************************************************/
  136. int IntrGetch(void)
  137. {
  138.     static unsigned int LastKey = 0;
  139.     unsigned int Key;
  140.     union REGS regs;
  141.  
  142. #ifdef __MSDOS__
  143.     if (IntrATKeyboard) {
  144.     if (LastKey) {
  145.         /* Last one was extended code, and we returned 0 instead. */
  146.         Key = LastKey;
  147.         LastKey = 0;
  148.         return Key;
  149.     }
  150.     else {
  151.         regs.h.ah = 0x10;
  152.         int86(0x16, ®s, ®s);
  153.         if (regs.h.al)
  154.         return regs.h.al;
  155.         else {
  156.         LastKey = regs.h.ah;
  157.         return 0;
  158.         }
  159.     }
  160.     }
  161.     else
  162.     return getch();
  163. #endif /* __MSDOS__ */
  164.  
  165. #ifdef DJGCC
  166.     if (LastKey) {
  167.     /* Last one was extended code, and we returned 0 instead. */
  168.     Key = LastKey;
  169.     LastKey = 0;
  170.     return Key;
  171.     }
  172.     else {
  173.     Key = getkey();
  174.     if (Key & 0xff00) {
  175.         LastKey = Key & 0xff;
  176.         return 0;
  177.     }
  178.     else {
  179.         return Key;
  180.     }
  181.     }
  182. #endif /* DJGCC */
  183. }
  184.  
  185. /****************************************************************************
  186. * Routine to test if character keyboard queue is not empty.            *
  187. ****************************************************************************/
  188. int IntrKbHit(void)
  189. {
  190. #ifdef DJGCC
  191.     union REGS regs;
  192.  
  193.     if (IntrATKeyboard) {
  194.     regs.h.ah = 0x11;
  195.     int86(0x16, ®s, ®s);
  196.     /* If Z flag clear - queue is no empty: */
  197.     return (regs.x.flags & 0x40) == 0;
  198.     }
  199.     else
  200. #endif /* DJGCC */
  201.     return kbhit();
  202. }
  203.  
  204. /****************************************************************************
  205. * Routine to flush keyboard buffer.                        *
  206. ****************************************************************************/
  207. static void IntrFlushKbd(void)
  208. {
  209.     while (IntrKbHit())
  210.     if (IntrGetch() == 0) IntrGetch();
  211. }
  212.  
  213. /****************************************************************************
  214. * Routine to update Dx, Dy coordinates According to key    pressed.        *
  215. * Returns Event (Select, abort, etc.)                        *
  216. ****************************************************************************/
  217. static int UpdateGetPointKbd(int *Dx, int *Dy)
  218. {
  219.     int    c, Event = INTR_EVNT_MOVE;
  220.  
  221.     *Dx = *Dy = 0;
  222.  
  223.     c = LastInputChar = IntrGetch();
  224.     if (c > 0 && (IsRegisteredKey(c) || _IntrDetachKbdFromMouse))
  225.         return INTR_EVNT_KEY;
  226.     else
  227.         switch (c) {
  228.             case 0:
  229.                 c = IntrGetch();
  230.                 LastInputChar = 256 + c;
  231.         if (IsRegisteredKey(c + 256) || _IntrDetachKbdFromMouse)
  232.                 return INTR_EVNT_KEY;
  233.         else
  234.                     switch (c) {
  235.             case 71:
  236.                 *Dx = -1;           /* Arrows - move 1 at a time. */
  237.                 *Dy = -1;
  238.                 break;
  239.             case 72:
  240.                 *Dy = -1;
  241.                 break;
  242.             case 73:
  243.                 *Dx = 1;
  244.                 *Dy = -1;
  245.                 break;
  246.             case 75:
  247.                 *Dx = -1;
  248.                 break;
  249.             case 77:
  250.                 *Dx = 1;
  251.                 break;
  252.             case 79:
  253.                 *Dx = -1;
  254.                 *Dy = 1;
  255.                 break;
  256.             case 80:
  257.                 *Dy = 1;
  258.                 break;
  259.             case 81:
  260.                 *Dx = 1;
  261.                 *Dy = 1;
  262.                 break;
  263.             default:
  264.                 Event = INTR_EVNT_KEY;
  265.                 break;
  266.             }
  267.         break;
  268.         case 9:
  269.         Event = INTR_EVNT_MIDDLE_BUTTON;
  270.         break;
  271.         case 10:
  272.         case 13:
  273.         Event = INTR_EVNT_SELECT;
  274.         break;
  275.         case ' ':
  276.         Event = INTR_EVNT_ABORT;
  277.         break;
  278.         case '1':
  279.         *Dx = -SHIFT_KEY_MOVES;              /* Shifted arrows. */
  280.             *Dy = SHIFT_KEY_MOVES;
  281.             break;
  282.         case '2':
  283.             *Dy = SHIFT_KEY_MOVES;
  284.             break;
  285.         case '3':
  286.             *Dx = SHIFT_KEY_MOVES;
  287.             *Dy = SHIFT_KEY_MOVES;
  288.             break;
  289.         case '4':
  290.             *Dx = -SHIFT_KEY_MOVES;
  291.             break;
  292.         case '6':
  293.             *Dx = SHIFT_KEY_MOVES;
  294.             break;
  295.         case '7':
  296.             *Dx = -SHIFT_KEY_MOVES;
  297.             *Dy = -SHIFT_KEY_MOVES;
  298.             break;
  299.         case '8':
  300.             *Dy = -SHIFT_KEY_MOVES;
  301.             break;
  302.         case '9':
  303.             *Dx = SHIFT_KEY_MOVES;
  304.             *Dy = -SHIFT_KEY_MOVES;
  305.             break;
  306.         default:
  307.             Event = INTR_EVNT_KEY;
  308.             break;
  309.     }
  310.  
  311.     return Event;
  312. }
  313.  
  314. /****************************************************************************
  315. * Routine to get joystick movement and/or joystick button press.        *
  316. * uses int 0x15 service 0x84 to detect joystick events.                *
  317. * Joystick is calibrated using JoystickCalibrate routine that sets the      *
  318. * following variables.:                                *
  319. * 1. JoystickCenterX, JoystickCenterY - center values (joystick rest pos.). *
  320. * 2. JoystickMinX, JoystickMinY - minimum values from joystick.            *
  321. * 3. JoystickMaxX, JoystickMaxX - maximum values from joystick.            *
  322. * 4. JoystickTolerance - %10 of Max - Min value.                *
  323. * Movement is assumed if value read differs from Center by Tolerance.        *
  324. * Amount of movement is set so JoystickMaxMove for extremum values.        *
  325. ****************************************************************************/
  326. static int JoystickMove(int *Dx, int *Dy, IntrEventType *Event)
  327. {
  328.     static int JoystickMaxMove = JOYSTICK_MAX_MOVE;
  329.     union REGS regs;
  330.  
  331.     *Event = INTR_EVNT_NONE;
  332.     *Dx = *Dy = 0;
  333.  
  334.     /* Test if joystick buttons has been pressed. */
  335.     regs.h.ah = 0x84;
  336.     regs.x.dx = 0x0000;
  337.     int86(0x15, ®s, ®s);
  338.     if ((regs.h.al & 0x30) == 0)
  339.     *Event = INTR_EVNT_MIDDLE_BUTTON;
  340.     else if ((regs.h.al & 0x10) == 0)
  341.     *Event = INTR_EVNT_SELECT;
  342.     else if ((regs.h.al & 0x20) == 0)
  343.     *Event = INTR_EVNT_ABORT;
  344.     if (*Event != INTR_EVNT_NONE) {
  345.         JoystickMaxMove = JOYSTICK_MAX_MOVE; /* Go back to minimum movement. */
  346.     return TRUE;
  347.     }
  348.  
  349.     /* Test if movement occured: */
  350.     regs.h.ah = 0x84;
  351.     regs.x.dx = 0x0001;
  352.     int86(0x15, ®s, ®s);
  353.     if (ABS(((int) regs.x.ax) - JoystickCenterX) > JoystickTolerance)
  354.     *Dx = (int) (JoystickMaxMove * (((int) regs.x.ax) - JoystickCenterX) /
  355.                 ((IntrRType) (JoystickMaxX - JoystickMinX)));
  356.     if (ABS(((int) regs.x.bx) - JoystickCenterY) > JoystickTolerance)
  357.     *Dy = (int) (JoystickMaxMove * (((int) regs.x.bx) - JoystickCenterY) /
  358.                 ((IntrRType) (JoystickMaxY - JoystickMinY)));
  359.     if (*Dx != 0 || *Dy != 0) {
  360.     *Event = INTR_EVNT_MOVE;
  361.         JoystickMaxMove += JOYSTICK_INC_MOVE;
  362.     return TRUE;
  363.     }
  364.     else
  365.         JoystickMaxMove = JOYSTICK_MAX_MOVE; /* Go back to minimum movement. */
  366.  
  367.     return FALSE;
  368. }
  369.  
  370. /****************************************************************************
  371. * Routine to wait until joystick button 0 is pressed.                     *
  372. * If the button is not pressed for 10 seconds NoJoystick is set to TRUE.    *
  373. ****************************************************************************/
  374. static void JoystickWaitButton0(void)
  375. {
  376.     int i;
  377.     union REGS regs;
  378.  
  379.     for (i = 0; i < 1000; i++) {
  380.     regs.h.ah = 0x84;
  381.     regs.x.dx = 0x0000;
  382.     int86(0x15, ®s, ®s);
  383.         if ((regs.x.ax & 0x10) == 0) return;
  384.         delay(10);                      /* 10 miliseconds. */
  385.     }
  386.     NoJoystick = TRUE;
  387. }
  388.  
  389. /****************************************************************************
  390. * Routine to wait until joystick button 1 is pressed.                     *
  391. * If the button is not pressed for 10 seconds NoJoystick is set to TRUE.    *
  392. ****************************************************************************/
  393. static void JoystickWaitButton1(void)
  394. {
  395.     int i;
  396.     union REGS regs;
  397.  
  398.     for (i = 0; i < 1000; i++) {
  399.     regs.h.ah = 0x84;
  400.     regs.x.dx = 0x0000;
  401.     int86(0x15, ®s, ®s);
  402.         if ((regs.x.ax & 0x20) == 0) return;
  403.         delay(10);                      /* 10 miliseconds. */
  404.     }
  405.     NoJoystick = TRUE;
  406. }
  407.  
  408. /****************************************************************************
  409. * Routine to initialize the joystick.                        *
  410. ****************************************************************************/
  411. static void JoystickInit(void)
  412. {
  413.     union REGS regs;
  414.     IntrCursorShapeStruct Cursor;
  415.  
  416.     Cursor.CursorType = INTR_CURSOR_ARROW;
  417.  
  418.     NoJoystick = FALSE;
  419.  
  420.     IntrQueryContinue2("Move Joystick to top left and press Button 0",
  421.                        JoystickWaitButton0,
  422.                    INTR_COLOR_RED,
  423.                        INTR_COLOR_BLUE,
  424.                        INTR_COLOR_YELLOW,
  425.                        8,
  426.                        &Cursor,
  427.                        0);
  428.     if (NoJoystick) {
  429.     _IntrActiveDevices &= ~INTR_INPT_DEVICE_JOYSTICK;
  430.         IntrQueryContinue("No joystick detected.",
  431.                       INTR_COLOR_RED,
  432.                           INTR_COLOR_BLUE,
  433.                           INTR_COLOR_YELLOW,
  434.                           INTR_COLOR_MAGENTA,
  435.                           8,
  436.                           &Cursor,
  437.                           0);
  438.         return;
  439.     }
  440.     regs.h.ah = 0x84;
  441.     regs.x.dx = 0x0001;
  442.     int86(0x15, ®s, ®s);
  443.     JoystickMinX = regs.x.ax;
  444.     JoystickMinY = regs.x.bx;
  445.  
  446.     IntrQueryContinue2("Move Joystick to bottom right and press Button 1",
  447.                        JoystickWaitButton1,
  448.                    INTR_COLOR_RED,
  449.                        INTR_COLOR_BLUE,
  450.                        INTR_COLOR_YELLOW,
  451.                        8,
  452.                        &Cursor,
  453.                        0);
  454.     if (NoJoystick) {
  455.     _IntrActiveDevices &= ~INTR_INPT_DEVICE_JOYSTICK;
  456.         IntrQueryContinue("No joystick detected.",
  457.                       INTR_COLOR_RED,
  458.                           INTR_COLOR_BLUE,
  459.                           INTR_COLOR_YELLOW,
  460.                           INTR_COLOR_MAGENTA,
  461.                           8,
  462.                           &Cursor,
  463.                           0);
  464.         return;
  465.     }
  466.     regs.h.ah = 0x84;
  467.     regs.x.dx = 0x0001;
  468.     int86(0x15, ®s, ®s);
  469.     JoystickMaxX = regs.x.ax;
  470.     JoystickMaxY = regs.x.bx;
  471.  
  472.     IntrQueryContinue2("Move Joystick to center and press Button 0",
  473.                        JoystickWaitButton0,
  474.                INTR_COLOR_RED,
  475.                        INTR_COLOR_BLUE,
  476.                        INTR_COLOR_YELLOW,
  477.                        8,
  478.                        &Cursor,
  479.                0);
  480.     if (NoJoystick) {
  481.     _IntrActiveDevices &= ~INTR_INPT_DEVICE_JOYSTICK;
  482.     IntrQueryContinue("No joystick detected.",
  483.               INTR_COLOR_RED,
  484.                           INTR_COLOR_BLUE,
  485.               INTR_COLOR_YELLOW,
  486.               INTR_COLOR_MAGENTA,
  487.               8,
  488.               &Cursor,
  489.               0);
  490.     return;
  491.     }
  492.     regs.h.ah = 0x84;
  493.     regs.x.dx = 0x0001;
  494.     int86(0x15, ®s, ®s);
  495.     JoystickCenterX = regs.x.ax;
  496.     JoystickCenterY = regs.x.bx;
  497.  
  498.     /* Make sure domain is not empty (prevent divide by zero). */
  499.     if (JoystickMinX == JoystickMaxX) JoystickMaxX++;
  500.     if (JoystickMinY == JoystickMaxY) JoystickMaxY++;
  501. }
  502.  
  503. /****************************************************************************
  504. * Routine to select devices to handle (see IntrInputDeviceType).        *
  505. ****************************************************************************/
  506. void IntrSetInputDevice(int Devices)
  507. {
  508.     int OldDevices = _IntrActiveDevices;
  509.  
  510.     _IntrActiveDevices = Devices;
  511.  
  512. #ifdef __MSDOS__
  513.     if (OldDevices & INTR_INPT_DEVICE_MOUSE &&
  514.     !(_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE)) {
  515.     /* Close the mouse interaction. */
  516.     MouseClose();
  517.     }
  518.     else if (!(OldDevices & INTR_INPT_DEVICE_MOUSE) &&
  519.          _IntrActiveDevices & INTR_INPT_DEVICE_MOUSE) {
  520.     /* Open a mouse interaction. */
  521.     MouseInit(MouseSensitivity);
  522.     }
  523. #endif /* __MSDOS__ */
  524.  
  525. #ifdef DJGCC
  526.     /* Make sure the mouse is initialized by invoking MouseGetEvent once */
  527.     /* and then initialize the mouse sensitivity as desired.         */
  528.     {
  529.     MouseEvent MEvent;
  530.  
  531.     MouseGetEvent(M_POLL | M_NOPAINT, &MEvent);
  532.     MouseSetSpeed(MouseSensitivity);
  533.     }
  534. #endif /* DJGCC */
  535.  
  536.     if (!(OldDevices & INTR_INPT_DEVICE_JOYSTICK) &&
  537.         _IntrActiveDevices & INTR_INPT_DEVICE_JOYSTICK) {
  538.         /* Set up the joystick. */
  539.         JoystickInit();
  540.     }
  541. }
  542.  
  543. /****************************************************************************
  544. * Routine to set Handling of internal events.                    *
  545. ****************************************************************************/
  546. void IntrSetHandleInternalEvents(IntrBType HandleEvents,
  547.                  IntrBType PropagateEvents)
  548. {
  549.     HandleInternalEvents = HandleEvents;
  550.     PropagateInternalEvents = PropagateEvents;
  551. }
  552.  
  553. /****************************************************************************
  554. * Same as IntrGetEventWait but waits for Abort or Select.            *
  555. ****************************************************************************/
  556. IntrEventType IntrGetEventWaitSA(int *x, int *y)
  557. {
  558.     IntrEventType Event;
  559.  
  560.     while ((Event = IntrGetEventWait(x, y)) != INTR_EVNT_SELECT &&
  561.        Event != INTR_EVNT_ABORT &&
  562.        Event != INTR_EVNT_MIDDLE_BUTTON);
  563.  
  564.     return Event;
  565. }
  566.  
  567.  
  568. /****************************************************************************
  569. * Routine to flush all input events.                        *
  570. ****************************************************************************/
  571. void IntrInputFlush(void)
  572. {
  573. #ifdef __MSDOS__
  574.     if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE)
  575.     MouseFlushBuffer();
  576. #endif /* __MSDOS__ */
  577.     if (_IntrActiveDevices & INTR_INPT_DEVICE_KEYBOARD)
  578.     IntrFlushKbd();
  579. }
  580.  
  581. /****************************************************************************
  582. * Routine to get one event - move in x, y, select, abort etc.            *
  583. * Note this routine returns x, y in screen coordinates.                *
  584. * This routine waits until event occurs.                    *
  585. ****************************************************************************/
  586. IntrEventType IntrGetEventWait(int *x, int *y)
  587. {
  588.     IntrEventType Event;
  589.     int OrigX = GRCurrentCursorX,
  590.         OrigY = GRCurrentCursorY;
  591.  
  592.     /* Read events while the events are internal. */
  593.     do {
  594.     if (IntrIdleFunction != NULL)
  595.         (IntrIdleFunction)();         /* Do something useful if idle. */
  596.  
  597.         IntrShowCursor(GRCurrentCursorX, /* Draw cursor - starting position. */
  598.                    GRCurrentCursorY);
  599.  
  600.         while ((Event = IntrGetEventNoWait(x, y)) == INTR_EVNT_NONE);
  601.  
  602.         if (Event == INTR_EVNT_MOVE) {
  603.             GRCurrentCursorX = OrigX = *x;
  604.         GRCurrentCursorY = OrigY = *y;
  605.         }
  606.         else {
  607.         GRCurrentCursorX = OrigX;
  608.         GRCurrentCursorY = OrigY;
  609.         }
  610.         IntrUnShowCursor();        /* Erase last old cursor before quiting. */
  611.     }
  612.     while (HandleInternalEvents &&
  613.            _IntrIsInternalEvent(Event, GRCurrentCursorX, GRCurrentCursorY) &&
  614.            !PropagateInternalEvents);
  615.  
  616. #ifndef DJGCC
  617.     /* Clear any pending events. */
  618.     if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE &&
  619.     (Event == INTR_EVNT_ABORT ||
  620.      Event == INTR_EVNT_MIDDLE_BUTTON ||
  621.      Event == INTR_EVNT_SELECT)) {
  622.     delay(250);
  623.     IntrInputFlush();
  624.     }
  625. #endif /* DJGCC */
  626.  
  627.     return Event;
  628. }
  629.  
  630. #ifdef DJGCC
  631.  
  632. /****************************************************************************
  633. * Emulate functions below using the mouse functions provided in DJGCC.        *
  634. ****************************************************************************/
  635. static MouseEvent MEvent;
  636.  
  637. static IntrBType MouseQueryBuffer(void)
  638. {
  639.     MouseGetEvent(M_POLL | M_NOPAINT | M_MOTION | M_BUTTON_DOWN, &MEvent);
  640.     if (MEvent.flags & M_KEYPRESS)
  641.  
  642.     return (MEvent.flags & M_BUTTON_DOWN) ||
  643.            ((MEvent.flags & M_MOTION) &&
  644.             (MEvent.x != GRCurrentCursorX || MEvent.y != GRCurrentCursorY));
  645. }
  646.  
  647. static void MouseGetBuffer(int *x, int *y, int *Buttons)
  648. {
  649.     *x = MEvent.x;
  650.     *y = MEvent.y;
  651.     if (MEvent.buttons & M_MIDDLE) 
  652.     *Buttons = 0x03;
  653.     else
  654.     *Buttons = MEvent.buttons;
  655. }
  656.  
  657. #endif /* DJGCC */
  658.  
  659. /****************************************************************************
  660. * Routine to get one event - move in x, y, select, abort etc.            *
  661. * Note this routine returns x, y in screen coordinates.                *
  662. * This routine does not wait if no event is waiting and no cursor is drawn. *
  663. ****************************************************************************/
  664. IntrEventType IntrGetEventNoWait(int *x, int *y)
  665. {
  666.     IntrEventType
  667.      Event = INTR_EVNT_NONE;
  668.     int    Buttons, Dx, Dy,
  669.         XScreen = GRCurrentCursorX,
  670.         YScreen = GRCurrentCursorY;
  671.  
  672.     if (PushedKbdEvent >= 0) {
  673.     *x = PushedKbdEvent;
  674.     PushedKbdEvent = -1;
  675.         return INTR_EVNT_KEY;
  676.     }
  677.     
  678.     /* Scan for input from one of the input devices. */
  679.     if (_IntrActiveDevices & INTR_INPT_DEVICE_KEYBOARD && IntrKbHit()) {
  680.     Event = UpdateGetPointKbd(&Dx, &Dy);
  681.     XScreen += Dx;
  682.     YScreen += Dy;
  683.     }
  684.     else if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE &&
  685.     MouseQueryBuffer()) {
  686.     MouseGetBuffer(&XScreen, &YScreen, &Buttons);
  687.     if (Buttons == 0x03)
  688.         Event = INTR_EVNT_MIDDLE_BUTTON;
  689.     else if (Buttons == 0x01)
  690.         Event = INTR_EVNT_SELECT;
  691.     else if (Buttons == 0x02)
  692.         Event = INTR_EVNT_ABORT;
  693.     }
  694.     else if (_IntrActiveDevices & INTR_INPT_DEVICE_JOYSTICK &&
  695.          JoystickMove(&Dx, &Dy, &Event)) {
  696.     XScreen += Dx;
  697.     YScreen += Dy;
  698.     }
  699.  
  700.     if (XScreen < 0) XScreen = 0;
  701.     if (YScreen < 0) YScreen = 0;
  702.     if (XScreen > GRScreenMaxX) XScreen = GRScreenMaxX;
  703.     if (YScreen > GRScreenMaxY) YScreen = GRScreenMaxY;
  704.  
  705.     if ((GRCurrentCursorX != XScreen || GRCurrentCursorY != YScreen) &&
  706.         Event == INTR_EVNT_NONE)
  707.     Event = INTR_EVNT_MOVE;
  708.  
  709.     switch (Event) {
  710.     case INTR_EVNT_KEY:
  711.             *x = LastInputChar;
  712.         break;
  713.     default:
  714.         *x = XScreen;
  715.         *y = YScreen;
  716.             break;
  717.     }
  718.  
  719.     return Event;
  720. }
  721.  
  722. /****************************************************************************
  723. * Routine to get one event - select, abort etc.                    *
  724. ****************************************************************************/
  725. IntrEventType IntrGetTextEventWait(void)
  726. {
  727.     IntrEventType
  728.         Event = INTR_EVNT_NONE;
  729.  
  730.     while ((Event = IntrGetTextEventNoWait()) == INTR_EVNT_NONE)
  731.     if (IntrIdleFunction != NULL)
  732.         (IntrIdleFunction)();         /* Do something useful if idle. */
  733.  
  734.  
  735.     return Event;
  736. }
  737.  
  738. /****************************************************************************
  739. * Routine to get one event - select, abort etc.                    *
  740. * This routine does not wait if no event is waiting and no cursor is drawn. *
  741. ****************************************************************************/
  742. IntrEventType IntrGetTextEventNoWait(void)
  743. {
  744.     int    Buttons,
  745.         Xtemp = 0,
  746.         Ytemp = 0;
  747.     IntrEventType
  748.         Event = INTR_EVNT_NONE;
  749.  
  750.     /* Wait for input from one of the devices: Mouse/Keyboard. */
  751.     if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE &&
  752.     MouseQueryBuffer()) {
  753.     MouseGetBuffer(&Xtemp, &Ytemp, &Buttons);
  754.     if (Buttons == 0x03)
  755.         Event = INTR_EVNT_MIDDLE_BUTTON;
  756.     else if (Buttons == 0x01)
  757.         Event = INTR_EVNT_SELECT;
  758.     else if (Buttons == 0x02)
  759.         Event = INTR_EVNT_ABORT;
  760.     if (Event == INTR_EVNT_MOVE) Event = INTR_EVNT_NONE;
  761.     }
  762.     else if (IntrKbHit()) {
  763.     switch (IntrGetch()) {
  764.         case 10:
  765.         case 13:
  766.         Event = INTR_EVNT_SELECT;
  767.         break;
  768.         case ' ':
  769.         Event = INTR_EVNT_ABORT;
  770.         break;
  771.     }
  772.     }
  773.     else if (_IntrActiveDevices & INTR_INPT_DEVICE_JOYSTICK)
  774.     JoystickMove(&Xtemp, &Ytemp, &Event);
  775.  
  776.     return Event;
  777. }
  778.  
  779. /****************************************************************************
  780. * One level stack ability to push keyboard event on the stack.            *
  781. ****************************************************************************/
  782. void IntrPushKbdEvent(int KbdEvent)
  783. {
  784.     PushedKbdEvent = KbdEvent;
  785. }
  786.  
  787. /****************************************************************************
  788. * Maps a screen (x, y) location into a window. Return TRUE if in window.    *
  789. ****************************************************************************/
  790. IntrBType IntrMapEventToWindow(int WindowID, int x, int y, int *Wx, int *Wy)
  791. {
  792.     _IntrWindowStruct
  793.     *Window = _IntrFindWndwUsingID(WindowID);
  794.  
  795.     if (_IntrWndwGetWndwInPos(x, y) != Window) return FALSE;
  796.  
  797.     *Wx = x - Window -> BBox.Xmin;
  798.     *Wy = y - Window -> BBox.Ymin;
  799.  
  800.     return TRUE;
  801. }
  802.  
  803. /****************************************************************************
  804. * Maps a screen (x, y) location into a window. Return TRUE if in window.    *
  805. ****************************************************************************/
  806. IntrBType IntrMapEventToRWindow(int WindowID, int x, int y,
  807.                           IntrRType *Wx, IntrRType *Wy)
  808. {
  809.     int ix, iy;
  810.     _IntrWindowStruct
  811.     *Window = _IntrFindWndwUsingID(WindowID);
  812.  
  813.     if (!IntrMapEventToWindow(WindowID, x, y, &ix, &iy))
  814.     return FALSE;
  815.  
  816.     *Wx = ix * Window -> FBBox._FDx / Window -> BBox._Dx +
  817.                             Window -> FBBox.FXmin;
  818.     *Wy = iy * Window -> FBBox._FDy / Window -> BBox._Dy +
  819.                             Window -> FBBox.FYmin;
  820.     return TRUE;
  821. }
  822.